home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Periodicals / develop / develop 10 code / GWorld Drawing / GWorld Routines / mapping.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-08  |  4.8 KB  |  184 lines  |  [TEXT/KAHL]

  1. #include "mapping.h"
  2.  
  3. /*    [ x  y ] [ a  b ] = [ newX  newY ]
  4.   *            [ c  d ]
  5.   */
  6. void MapXY(const mapping* map, Fixed* x, Fixed* y)
  7. {
  8.     const Fixed* mx = &map->map[0][0];
  9.     const Fixed* my = &map->map[1][0];
  10.     const Fixed* mt = &map->map[2][0];
  11.     Fixed tmpX = *x;
  12.     Fixed tmpY = *y;
  13.  
  14.     *x = FixMul(*mx++, tmpX) + FixMul(*my++, tmpY) + *mt++;
  15.     *y = FixMul(*mx, tmpX) + FixMul(*my, tmpY) + *mt++;
  16. }
  17.  
  18. static Fixed ComputeDeterminant(const mapping* map)
  19. {
  20.     return FixMul(map->map[0][0], map->map[1][1]) - FixMul(map->map[0][1], map->map[1][0]);
  21. }
  22.  
  23. mapping* InvertMapping(mapping* map)
  24. {
  25.     mapping inverse;
  26.     Fixed det = ComputeDeterminant(map);
  27.  
  28.     if (det == 0)
  29.         Debugger();
  30.     inverse.map[0][0] = FixDiv(map->map[1][1], det);
  31.     inverse.map[0][1] = - FixDiv(map->map[0][1], det);
  32.     inverse.map[1][0] = - FixDiv(map->map[1][0], det);
  33.     inverse.map[1][1] = FixDiv(map->map[0][0], det);
  34.     inverse.map[2][0] = - FixMul(map->map[2][0], inverse.map[0][0]) - FixMul(map->map[2][1], inverse.map[1][0]);
  35.     inverse.map[2][1] = - FixMul(map->map[2][0], inverse.map[0][1]) - FixMul(map->map[2][1], inverse.map[1][1]);
  36.     *map = inverse;
  37.  
  38.     return map;
  39. }
  40.  
  41. mapping* SetIdentityMapping(mapping* map)
  42. {
  43.     Fixed* m = &map->map[0][0];
  44.  
  45.     *m++ = ff(1); *m++ = 0;
  46.     *m++ = 0; *m++ = ff(1);
  47.     *m++ = 0; *m++ = 0;
  48.     
  49.     return map;
  50. }
  51.  
  52. mapping* ScaleMapping(mapping* map, Fixed scaleX, Fixed scaleY, Fixed aboutX, Fixed aboutY)
  53. {
  54.     mapping scaleMap;
  55.     
  56.     SetIdentityMapping(&scaleMap);
  57.     scaleMap.map[0][0] = scaleX;
  58.     scaleMap.map[1][1] = scaleY;
  59.     scaleMap.map[2][0] = aboutX - FixMul(scaleX, aboutX);
  60.     scaleMap.map[2][1] = aboutY - FixMul(scaleY, aboutY);
  61.  
  62.     return ConcateMapping(map, &scaleMap);
  63. }
  64.  
  65. Boolean IdentityMapping(const mapping* map)
  66. {
  67.     return map->map[0][0] == ff(1) && map->map[1][1] == ff(1) &&
  68.             !map->map[0][1] && !map->map[1][0] && !map->map[2][0] && !map->map[2][1];
  69. }
  70.  
  71. mapping* ConcateMapping(mapping* dst, const mapping* map)
  72. {
  73.     mapping concat;
  74.  
  75.     concat.map[0][0] = FixMul(dst->map[0][0], map->map[0][0]) + FixMul(dst->map[0][1], map->map[1][0]);
  76.     concat.map[0][1] = FixMul(dst->map[0][0], map->map[0][1]) + FixMul(dst->map[0][1], map->map[1][1]);
  77.     concat.map[1][0] = FixMul(dst->map[1][0], map->map[0][0]) + FixMul(dst->map[1][1], map->map[1][0]);
  78.     concat.map[1][1] = FixMul(dst->map[1][0], map->map[0][1]) + FixMul(dst->map[1][1], map->map[1][1]);
  79.     concat.map[2][0] = FixMul(dst->map[2][0], map->map[0][0]) + FixMul(dst->map[2][1], map->map[1][0]) + map->map[2][0];
  80.     concat.map[2][1] = FixMul(dst->map[2][0], map->map[0][1]) + FixMul(dst->map[2][1], map->map[1][1]) + map->map[2][1];
  81.  
  82.     *dst = concat;
  83.     return dst;
  84. }
  85.  
  86. #define piOver180Frac    18740330L
  87.  
  88. mapping* RotateMapping(mapping* map, Fixed angle, Fixed aboutX, Fixed aboutY)
  89. {
  90.     mapping rotateMap;
  91.     Fixed radians = FracMul(angle, piOver180Frac);
  92.  
  93.     rotateMap.map[0][0] = Frac2Fix(FracCos(radians));
  94.     rotateMap.map[0][1] = - Frac2Fix(FracSin(radians));
  95.     rotateMap.map[1][0] = - rotateMap.map[0][1];
  96.     rotateMap.map[1][1] = rotateMap.map[0][0];
  97.     rotateMap.map[2][0] = aboutX - FixMul(rotateMap.map[0][0], aboutX) - FixMul(rotateMap.map[1][0], aboutY);
  98.     rotateMap.map[2][1] = aboutY - FixMul(rotateMap.map[0][1], aboutX) - FixMul(rotateMap.map[1][1], aboutY);
  99.  
  100.     if (IdentityMapping(map))
  101.         *map = rotateMap;
  102.     else
  103.         ConcateMapping(map, &rotateMap);
  104.     return map;
  105. }
  106.  
  107. mapping* OffsetMapping(mapping* map, Fixed offsetX, Fixed offsetY)
  108. {
  109.     map->map[2][0] += offsetX;
  110.     map->map[2][1] += offsetY;
  111.  
  112.     return map;
  113. }
  114.  
  115. Point* MapQDPoint(const mapping* map, Point* p)
  116. {
  117.     Fixed x, y;
  118.  
  119.     x = ff(p->h);
  120.     y = ff(p->v);
  121.     MapXY(map, &x, &y);
  122.     p->h = FixRound(x);
  123.     p->v = FixRound(y);
  124.  
  125.     return p;
  126. }
  127.  
  128. static void FlipRect(Rect* r)
  129. {
  130.     if (r->top > r->bottom)
  131.     {    short tmp = r->top;
  132.         r->top = r->bottom;
  133.         r->bottom = tmp;
  134.     }
  135.     if (r->left > r->right)
  136.     {    short tmp = r->left;
  137.         r->left = r->right;
  138.         r->right = tmp;
  139.     }
  140. }
  141.  
  142. static void ExtendRect(Rect* r, Point p)
  143. {
  144.     if (p.h < r->left)
  145.         r->left = p.h;
  146.     else if (p.h > r->right)
  147.         r->right = p.h;
  148.  
  149.     if (p.v < r->top)
  150.         r->top = p.v;
  151.     else if (p.v > r->bottom)
  152.         r->bottom = p.v;
  153. }
  154.  
  155. Rect* MapRectangle(const mapping* map, Rect* r)
  156. {
  157.     Rect bounds;
  158.     Point p;
  159.  
  160.     SetPt(&p, r->left, r->top); MapQDPoint(map, &p); SetRect(&bounds, p.h, p.v, p.h, p.v);
  161.     SetPt(&p, r->right, r->top); MapQDPoint(map, &p); ExtendRect(&bounds, p);
  162.     SetPt(&p, r->right, r->bottom); MapQDPoint(map, &p); ExtendRect(&bounds, p);
  163.     SetPt(&p, r->left, r->bottom); MapQDPoint(map, &p); ExtendRect(&bounds, p);
  164.     *r = bounds;
  165.  
  166.     return r;
  167. }
  168.  
  169. RgnHandle MapRectToRgn(const mapping* map, const Rect* r, RgnHandle rgn)
  170. {
  171.     Point p, start;
  172.  
  173.     OpenRgn();
  174.     SetPt(&p, r->left, r->top); MapQDPoint(map, &p); MoveTo(p.h, p.v); start = p;
  175.     SetPt(&p, r->right, r->top); MapQDPoint(map, &p); LineTo(p.h, p.v);
  176.     SetPt(&p, r->right, r->bottom); MapQDPoint(map, &p); LineTo(p.h, p.v);
  177.     SetPt(&p, r->left, r->bottom); MapQDPoint(map, &p); LineTo(p.h, p.v);
  178.     LineTo(start.h, start.v);
  179.     CloseRgn(rgn);
  180.     
  181.     return rgn;
  182. }
  183.  
  184.